/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */
package jp.ize.ux.components;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.UXController;
import jp.ize.ux.UXInteraction;
import jp.ize.ux.UXFocusManager;
import jp.ize.ux.acts.Act;
import jp.ize.ux.components.UXComponent;
import jp.ize.ux.components.UXComponentResource;
import jp.ize.ux.interactions.UXGeneralInteraction;
import jp.ize.ux.states.UXBasicState;
import jp.ize.ux.events.UXEvent;
import jp.ize.ux.events.UXMouseEvent;
import jp.ize.ux.events.UXKeyboardEvent;
import jp.ize.ux.geom.UXPoint;

#if flash9
import flash.ui.Keyboard;
#elseif flash
import flash.Key;
#end
// }}}
// {{{ class UXItemAct extends Act
/**
 * UXItemAct クラス<br>
 * UXItemのデフォルトアクションです。
 */
class UXItemAct extends Act
{
	// {{{ public function new()
	/**
	 * コンストラクタです。<br>
	 */
	public function new()
	{
		super();
	}
	// }}}
	// {{{ public function normal() : UXItemState->Void
	/**
	 * アイテムが実行された時のデフォルトアクションです。
	 */
	public function normal() : UXItemState->Void
	{
		return function (s:UXItemState) {
			if ( s.enabled ) {
				if ( s.highlighted ) {
					s.resource.highlighted();
					s.label.textColor = s.label.state.colors.highlight;
				} else if ( s.focused ) {
					s.resource.focused();
					s.label.textColor = s.label.state.colors.focus;
				} else if ( s.selected ) {
					s.resource.setState(UXComponentResource.SELECTED);
					s.label.textColor = s.label.state.colors.select;
				} else {
					s.resource.normal();
					s.label.textColor = s.label.state.colors.normal;
				}
			} else {
				s.resource.disabled();
				s.label.textColor = s.label.state.colors.disable;
			}
		}
	}
	// }}}
	// {{{ public function press() : UXItemState->Void
	/**
	 * アイテムが実行された時のデフォルトアクションです。
	 */
	public function press() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.resource.pressed();
			s.label.textColor = s.label.state.colors.press;
		}
		//s.resource.press.applyFilter( s.background );
		//s.resource.press.tween( s.background );
	}
	// }}}
	// {{{ public function highlight() : UXItemState->Void
	/**
	 * アイテムをハイライトした時のデフォルトアクションです。
	 */
	public function highlight() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.highlighted = true;
			s.resource.highlighted();
			s.label.textColor = s.label.state.colors.highlight;
		}
	}
	// }}}
	// {{{ public function unhighlight() : UXItemState->Void
	/**
	 * アイテムをハイライトした時のデフォルトアクションです。
	 */
	public function unhighlight() : UXItemState->Void
	{
		var me = this;
		return function (s:UXItemState) {
			s.highlighted = false;
			var f = me.normal();
			f(s);
		}
	}
	// }}}
	// {{{ public function select() : UXItemState->Void
	/**
	 * アイテムを選択した時のデフォルトアクションです。
	 */
	public function select() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.selected = true;
			s.resource.setState(UXComponentResource.SELECTED);
			s.label.textColor = s.label.state.colors.select;
			var e = new UXEvent(UXEvent.SELECTED);
			e.setTarget(s.target);
			s.target.dispatchEvent(e);
		}
	}
	// }}}
	// {{{ public function deselect() : UXItemState->Void
	/**
	 * アイテムの選択を解除した時のデフォルトアクションです。
	 */
	public function deselect() : UXItemState->Void
	{
		var me = this;
		return function (s:UXItemState) {
			s.selected = false;
			var f = me.normal();
			f(s);
			var e = new UXEvent(UXEvent.DESELECTED);
			e.setTarget(s.target);
			s.target.dispatchEvent(e);
		}
	}
	// }}}
	// {{{ public function focus() : UXItemState->Void
	/**
	 * アイテムがフォーカスされた時のデフォルトアクションです。
	 */
	public function focus() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.focused = true;
			s.resource.focused();
			s.label.textColor = s.label.state.colors.focus;
		}
	}
	// }}}
	// {{{ public function unfocus() : UXItemState->Void
	/**
	 * アイテムのフォーカスが解除された時のデフォルトアクションです。
	 */
	public function unfocus() : UXItemState->Void
	{
		var me = this;
		return function (s:UXItemState) {
			s.focused = false;
			var f = me.normal();
			f(s);
		}
	}
	// }}}
	// {{{ public function enable() : UXItemState->Void
	/**
	 * 有効にした時のデフォルトアクションです。
	 */
	public function enable() : UXItemState->Void
	{
		var me = this;
		return function (s:UXItemState) {
			s.enabled = true;
			var f = me.normal();
			f(s);
		}
	}
	// }}}
	// {{{ public function disable() : UXItemState->Void
	/**
	 * 無効にした時のデフォルトアクションです。
	 */
	public function disable() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.enabled = false;
			s.resource.disabled();
			s.label.textColor = s.label.state.colors.disable;
		}
	}
	// }}}
	// {{{ public function show() : UXItemState->Void
	/**
	 * 表示された時のデフォルトアクションです。
	 */
	public function show() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.resource.visible = true;
		}
	}
	// }}}
	// {{{ public function hide() : UXItemState->Void
	/**
	 * 非表示になった時のデフォルトアクションdす。
	 */
	public function hide() : UXItemState->Void
	{
		return function (s:UXItemState) {
			s.resource.visible = false;
		}
	}
	// }}}
}
// }}}
// {{{ class UXItemState
/**
 * UXItemState クラス<br>
 * UXItemの現在の状態を表すオブジェクトです。
 * UXItemStateはテキストやアイコンを直線的に配置するため、UXLinearStateを用います。
 */
//class UXItemState extends UXLinearState
class UXItemState extends UXBasicState
{
	// {{{ public var resource( default, default ) : UXItemResource;
	/**
	 * アイテムの描画に使用するリソースです。
	 */
	public var resource( default, default ) : UXComponentResource;
	// }}}
	// {{{ public var label(default, default) : UXLabel
	/**
	 * アイテム上に文字を表示するコンポーネントです。
	 */
	public var label(default, default) : UXLabel;
	// }}}
	// {{{ public var value(default, default) : Dynamic
	/**
	 * アイテム上に文字を表示するコンポーネントです。
	 */
	public var value(default, default) : Dynamic;
	// }}}
	// {{{ public var icon( default, default ) : Image;
	/**
	 * アイテム上に画像を表示するアイコンです。デフォルトではnullです。
	 */
	public var icon( default, default ) : UXImage;
	// }}}
	// {{{ public var acts(default, null) : UXItemAct
	/**
	 * デフォルトのアイテムの動きです。
	 */
	public var acts(default, null) : UXItemAct;
	// }}}
	// {{{ public function new( ?res:UXComponentResource, ?lbl:UXLabel, ?ico:UXImage ) : Void
	/**
	 * コンストラクタです。
	 *
	 * @param res: リソースの指定です。
	 * @param lbl: UXLabel（ラベル）の指定です。
	 * @param ico: UXImage（アイコン）の指定です。
	 */
	public function new( ?res:UXComponentResource, ?lbl:UXLabel, ?ico:UXImage ) : Void
	{
		super();
		if ( res==null ) res = new UXComponentResource();
		if ( lbl==null ) lbl = new UXLabel();
		resource  = res;
		label     = lbl;
		icon      = ico;
		acts      = new UXItemAct();
		if ( label!=null ) {
			label.label.selectable = false;
		}
		resource.normal();
	}
	// }}}
	// {{{ private function attachResource() : Void
	/**
	 * アイテムに対するグローバルなリソースをresourceプロパティに取得する関数です。
	 */
	private function attachResource() : Void
	{
	}
	// }}}
}
// }}}

// {{{ class UXItem extends UXComponent
/**
 * UXItem クラス<br>
 * アイテムを実現するコンポーネントです。アイテムは一つの背景コンポーネントと複数の前面コンポーネン
 * トがLinearLayoutされているものと定義されています。<br>
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id: UXItem.hx 20 2009-02-04 08:23:19Z yimai.v $<br>
 */
class UXItem extends UXComponent<UXItemState>
{
	// {{{ public function new( ?res:UXComponentResource, ?label:UXLabel, ?val:Dynamic, ?icon:UXImage = null )
	/**
	 * コンストラクタです。
	 * @param res: アイテムのリソースです。省略可能です。
	 * @param label: アイテムのテキストラベル（UXLabel）です。省略可能です。
	 * @param val: アイテムの持つ値です。任意のオブジェクトを指定可能です。省略可能です。
	 * @param icon: アイテムに表示する画像です。省略可能です。
	 */
	public function new( ?res:UXComponentResource, ?label:UXLabel, ?val:Dynamic, ?icon:UXImage = null )
	{
		// レイアウトとアクトのインスタンスを作ります。
		state = new UXItemState(res,label);
		state.target = this;
		state.value = val;
		state.icon = icon;
		ctrl = new UXController<UXItemState>( state );
		ctrl.addInteraction( new UXItemRollOverInteraction() );
		ctrl.addInteraction( new UXItemRollOutInteraction() );
		super(ctrl);
		if ( res!=null ) {
			addUXChild(res);
		} else {
			res = state.resource;
			res.graphics.beginFill(0x0000FF,0.0);
			res.graphics.drawRect(0,0,100,100);
			res.graphics.endFill();
			addUXChild(res);
		}
		var slabel = state.label.label;
		slabel.width  = res.width;
		slabel.height = res.height;
		state.label.x = res.width/2 - slabel.textWidth/2;
		state.label.y = res.height/2 - (slabel.textHeight+6)/2;
		res.addUXChild(state.label);

		ctrl.getInteraction("RollOver").addReactEvent(UXMouseEvent.ROLL_OVER);
		ctrl.getInteraction("RollOut").addReactEvent(UXMouseEvent.ROLL_OUT);

		ctrl.getInteraction("RollOver").addAct(state.acts.highlight());
		ctrl.getInteraction("RollOut").addAct(state.acts.unhighlight());
	}
	// }}}
	// {{{ public function refreshResource() : Void
	/**
	 * アイテムに対するグローバルなリソースを再取得する関数です。
	 */
	public function refreshResource() : Void
	{
		state.resource.normal();
	}
	// }}}
	// {{{ public function update( updator : UXItemState -> Void ) : Void
	/**
	 * このコンポーネントの状態を直接変更するメソッドです。状態のどんな操作も可能になるので、
	 * このメソッドの使用には注意が必要です。
	 */
	public function update( updator : UXItemState -> Void ) : Void
	{
		updator( state );
	}
	// }}}
	// {{{ public function hitTest( t:Dynamic ) : Bool
	/**
	* このオブジェクトの子要素であるかどうかを調べます
	*/
	public function hitTest( t:Dynamic ) : Bool
	{
		return this.contains(t);
		/*
		return ( t==this
				|| t==state.resource
				|| t==state.resource.resource
				|| t==state.icon
				|| t==state.label
				|| t==state.label.label );
		*/
	}

	// }}}
	// {{{ public function getValue() : Dynamic

	public function getValue() : Dynamic
	{
		return state.value;
	}

	// }}}
}
// }}}

// {{{ class UXItemRollOverInteraction extends UXGeneralInteraction<UXItemState>
/**
 * UXItemRollOverInteraction クラス<br>
 * アイテムの実行に対するデフォルトインタラクションです。
 */
class UXItemRollOverInteraction extends UXGeneralInteraction<UXItemState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("RollOver");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXItemRollOutInteraction extends UXGeneralInteraction<UXItemState>
/**
 * UXItemRollOutInteraction クラス<br>
 * アイテムの実行に対するデフォルトインタラクションです。
 */
class UXItemRollOutInteraction extends UXGeneralInteraction<UXItemState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("RollOut");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
